#include "Tank.hpp"
#include "Game.hpp"
#include <cmath>

sf::Texture Tank::playerTexture;
sf::Texture Tank::enemyTexture;
sf::Texture Tank::explosionTexture;
bool Tank::texturesLoaded = false;

void Tank::loadTextures() {
    if (!texturesLoaded) {
        if (!playerTexture.loadFromFile("resources/textures/tank_player.png")) {
            throw std::runtime_error("Failed to load player tank texture");
        }
        if (!enemyTexture.loadFromFile("resources/textures/tank_enemy.png")) {
            throw std::runtime_error("Failed to load enemy tank texture");
        }
        if (!explosionTexture.loadFromFile("resources/textures/explosion.png")) {
            throw std::runtime_error("Failed to load explosion texture");
        }
        texturesLoaded = true;
    }
}

Tank::Tank(Type type, const sf::Vector2f& position, Game& game)
    : mGame(game)
    , mType(type)
    , mPosition(position)
    , mLastPosition(position)
    , mRotation(0.f)
    , mSpeed(GRID_SIZE * 4.f)  // 每秒移动4个网格
    , mHealth(100)
    , mIsSpawning(type == Type::Enemy)  // 只有敌人坦克需要出现动画
    , mSpawnAlpha(0.f)
{
    // 启动射击计时器
    mShootingClock.restart();
    loadTextures();
    createSprite();
    
    // 确保初始位置对齐到网格
    alignToGrid();
    mLastPosition = mPosition;
    
    // 敌人坦克初始朝向向下
    if (mType == Type::Enemy) {
        mRotation = 180;
        mSprite.setRotation(mRotation);
        mCurrentDirection = Direction::Down;
        mSprite.setColor(sf::Color(255, 255, 255, 0));  // 初始完全透明
    }
}

void Tank::createSprite() {
    mSprite.setTexture(mType == Type::Player ? playerTexture : enemyTexture);
    
    // 获取纹理的原始尺寸
    sf::Vector2u textureSize = mSprite.getTexture()->getSize();
    
    // 计算缩放比例
    float scaleX = TANK_WIDTH / textureSize.x;
    float scaleY = TANK_HEIGHT / textureSize.y;
    mSprite.setScale(scaleX, scaleY);
    
    // 设置原点为中心点
    mSprite.setOrigin(textureSize.x / 2.f, textureSize.y / 2.f);
    mSprite.setPosition(mPosition);
}

void Tank::handleInput(bool isMovingUp, bool isMovingDown,
                        bool isMovingLeft, bool isMovingRight,
                        bool isShooting) {
    // 首先处理射击操作
    if (isShooting) {
        shoot();
    }
    
    // 保存当前位置用于可能的回退
    mLastPosition = mPosition;
    
    // 计算移动速度
    float movement = mSpeed / 60.f;  // 每帧移动速度
    
    // 检查是否在草地上
    if (mGame.getMap().isInGrass(getBounds())) {
        movement *= 0.5f;  // 在草地上速度减半
    }
    // 检查是否在冰块上
    else if (mGame.getMap().isOnIce(getBounds())) {
        movement *= 2.0f;  // 在冰块上速度加倍
    }
    
    // 根据按键设置方向并移动
    if (isMovingUp) {
        setDirection(Direction::Up);
        move(sf::Vector2f(0, -movement));
    }
    if (isMovingDown) {
        setDirection(Direction::Down);
        move(sf::Vector2f(0, movement));
    }
    if (isMovingLeft) {
        setDirection(Direction::Left);
        move(sf::Vector2f(-movement, 0));
    }
    if (isMovingRight) {
        setDirection(Direction::Right);
        move(sf::Vector2f(movement, 0));
    }
}

void Tank::setDirection(Direction dir) {
    // 只有当方向真正改变时才播放音效
    if (mCurrentDirection != dir && mType == Type::Player) {
        mGame.playTurnSound();
    }
    
    mCurrentDirection = dir;
    switch (dir) {
        case Direction::Up:
            mRotation = 0;
            break;
        case Direction::Right:
            mRotation = 90;
            break;
        case Direction::Down:
            mRotation = 180;
            break;
        case Direction::Left:
            mRotation = 270;
            break;
    }
    mSprite.setRotation(mRotation);
}

void Tank::update(sf::Time deltaTime) {
    // 处理出现动画
    if (mIsSpawning) {
        mSpawnAlpha += deltaTime.asSeconds() * (255.f / SPAWN_DURATION);
        if (mSpawnAlpha >= 255.f) {
            mSpawnAlpha = 255.f;
            mIsSpawning = false;
        }
        mSprite.setColor(sf::Color(255, 255, 255, static_cast<sf::Uint8>(mSpawnAlpha)));
        return;  // 在出现动画期间不进行其他更新
    }

    // 处理爆炸动画
    if (mIsExploding) {
        if (mExplosionClock.getElapsedTime().asSeconds() >= EXPLOSION_DURATION) {
            mIsExploding = false;
            mIsExploded = true;
            // 如果是玩家坦克被击毁，触发游戏结束
            if (mType == Type::Player) {
                mGame.setGameOver(true);
            }
        }
        return;
    }
    
    // 如果坦克已经死亡或爆炸完成，不再更新
    if (mHealth <= 0 || mIsExploded) {
        return;
    }
    
    // 如果是敌人，实现智能的AI行为
    if (mType == Type::Enemy) {
        // 保存当前位置用于可能的回退
        mLastPosition = mPosition;
        
        // 计算到玩家的方向
        sf::Vector2f toPlayer = mPlayerPosition - mPosition;
        float distanceToPlayer = std::sqrt(toPlayer.x * toPlayer.x + toPlayer.y * toPlayer.y);
        
        if (distanceToPlayer > 0) {
            // 标准化方向向量
            toPlayer /= distanceToPlayer;
            
            // 计算角度（弧度）
            float angleToPlayer = std::atan2(toPlayer.x, -toPlayer.y);
            // 转换为角度
            float angleInDegrees = angleToPlayer * 180.f / M_PI;
            if (angleInDegrees < 0) {
                angleInDegrees += 360.f;
            }
            
            // 随机决定是否改变移动方向
            static sf::Clock directionChangeClock;
            if (directionChangeClock.getElapsedTime().asSeconds() > 1.0f) {
                if (rand() % 100 < 30) { // 30%的概率改变方向
                    // 随机选择一个方向
                    int randomDir = rand() % 4;
                    switch (randomDir) {
                        case 0: setDirection(Direction::Up); break;
                        case 1: setDirection(Direction::Right); break;
                        case 2: setDirection(Direction::Down); break;
                        case 3: setDirection(Direction::Left); break;
                    }
                } else {
                    // 70%的概率朝向玩家
                    if (angleInDegrees <= 45.f || angleInDegrees > 315.f) {
                        setDirection(Direction::Up);
                    } else if (angleInDegrees <= 135.f) {
                        setDirection(Direction::Right);
                    } else if (angleInDegrees <= 225.f) {
                        setDirection(Direction::Down);
                    } else {
                        setDirection(Direction::Left);
                    }
                }
                directionChangeClock.restart();
            }
            
            // 计算移动速度
            float movement = mSpeed * deltaTime.asSeconds();
            
            // 检查是否在草地上
            if (mGame.getMap().isInGrass(getBounds())) {
                movement *= 0.5f;  // 在草地上速度减半
            }
            // 检查是否在冰块上
            else if (mGame.getMap().isOnIce(getBounds())) {
                movement *= 2.0f;  // 在冰块上速度加倍
            }
            
            float angle = mRotation * M_PI / 180.f;
            move(sf::Vector2f(std::sin(angle) * movement,
                            -std::cos(angle) * movement));
            
            // 根据与玩家的距离决定射击频率
            int shootChance = (distanceToPlayer < 200.f) ? 30 : 15; // 近距离时提高射击频率
            if (rand() % 100 < shootChance) {
                shoot();
            }
        }
    }
    
    // 更新子弹
    updateBullets(deltaTime);
}

void Tank::updateBullets(sf::Time deltaTime) {
    // 更新现有子弹
    for (auto it = mBullets.begin(); it != mBullets.end();) {
        (*it)->update(deltaTime);
        
        // 检查是否需要删除子弹
        bool shouldDelete = false;
        
        // 检查子弹是否超出屏幕范围
        if ((*it)->isOutOfBounds()) {
            shouldDelete = true;
        }
        
        // 检查子弹是否超过最大存在时间（3秒）
        if ((*it)->getLifetime().asSeconds() > 3.0f) {
            shouldDelete = true;
        }
        
        // 如果需要删除子弹
        if (shouldDelete) {
            it = mBullets.erase(it);
        } else {
            ++it;
        }
    }
}

void Tank::render(sf::RenderWindow& window) {
    if (mIsExploding) {
        // 渲染爆炸动画
        sf::Sprite explosionSprite(explosionTexture);
        explosionSprite.setOrigin(TANK_WIDTH / 2.f, TANK_HEIGHT / 2.f);
        explosionSprite.setPosition(mPosition);
        window.draw(explosionSprite);
    } else if (!mIsExploded) {
        // 渲染坦克（只有在没有爆炸的情况下）
        window.draw(mSprite);
    }
    
    // 渲染子弹
    for (const auto& bullet : mBullets) {
        bullet->render(window);
    }
}

void Tank::move(const sf::Vector2f& offset) {
    mPosition += offset;
    
    // 确保坦克不会移出屏幕边界
    mPosition.x = std::max(0.f, std::min(mPosition.x, MAP_WIDTH));
    mPosition.y = std::max(0.f, std::min(mPosition.y, MAP_HEIGHT));
    
    mSprite.setPosition(mPosition);
}

void Tank::shoot() {
    // 检查射击间隔
    if (mShootingClock.getElapsedTime().asSeconds() < SHOT_INTERVAL) {
        return;  // 如果间隔不够，直接返回
    }
    
    // 检查子弹数量限制
    if (mBullets.size() >= 5) {
        return;  // 如果子弹数量达到上限，直接返回
    }
    
    // 计算炮筒前端的精确位置
    float angle = mRotation * M_PI / 180.f;
    
    // 获取坦克的实际尺寸
    sf::Vector2u textureSize = mSprite.getTexture()->getSize();
    float tankScale = TANK_HEIGHT / textureSize.y;  // 使用实际的缩放比例
    
    // 计算炮筒长度（坦克高度的60%）和炮筒位置（从坦克中心点偏移）
    float barrelLength = TANK_HEIGHT * 0.6f;
    float barrelOffset = TANK_HEIGHT * 0.1f;  // 稍微向前偏移以对齐炮筒
    
    // 计算子弹的精确初始位置
    sf::Vector2f bulletOffset(
        std::sin(angle) * (barrelLength + barrelOffset),
        -std::cos(angle) * (barrelLength + barrelOffset)
    );
    
    // 创建新子弹，从炮筒前端发射
    mBullets.push_back(std::make_unique<Bullet>(
        mPosition + bulletOffset,  // 炮筒前端位置
        mRotation                 // 保持与坦克相同的朝向
    ));
    
    // 重置射击计时器
    mShootingClock.restart();
}

void Tank::damage(int amount) {
    mHealth = std::max(0, mHealth - amount);
    
    // 如果生命值降为0，开始爆炸动画
    if (mHealth == 0 && !mIsExploding && !mIsExploded) {
        mIsExploding = true;
        mExplosionClock.restart();
    }
}

void Tank::undoLastMove() {
    // 简单地回退到上一个位置
    mPosition = mLastPosition;
    mSprite.setPosition(mPosition);
}

sf::FloatRect Tank::getBounds() const {
    return mSprite.getGlobalBounds();
}

bool Tank::checkBulletCollisions(Map& map) {
    bool collision = false;
    
    // 检查所有子弹
    for (auto it = mBullets.begin(); it != mBullets.end();) {
        if (map.handleBulletCollision((*it)->getBounds())) {
            it = mBullets.erase(it);
            collision = true;
        } else {
            ++it;
        }
    }
    
    return collision;
}

bool Tank::checkBulletCollisions(Tank& other) {
    bool collision = false;
    
    // 检查所有子弹是否击中其他坦克
    for (auto it = mBullets.begin(); it != mBullets.end();) {
        if ((*it)->getBounds().intersects(other.getBounds())) {
            it = mBullets.erase(it);
            collision = true;
        } else {
            ++it;
        }
    }
    
    return collision;
}

bool Tank::checkBulletCollisionsWithBullets(Tank& other) {
    bool collision = false;
    
    // 检查本坦克的子弹是否与其他坦克的子弹相撞
    for (auto it1 = mBullets.begin(); it1 != mBullets.end();) {
        bool bulletCollided = false;
        
        // 检查与其他坦克的所有子弹
        for (auto it2 = other.mBullets.begin(); it2 != other.mBullets.end();) {
            if ((*it1)->getBounds().intersects((*it2)->getBounds())) {
                // 两颗子弹相撞，都需要删除
                it2 = other.mBullets.erase(it2);
                bulletCollided = true;
                collision = true;
            } else {
                ++it2;
            }
        }
        
        // 如果当前子弹发生碰撞，删除它
        if (bulletCollided) {
            it1 = mBullets.erase(it1);
        } else {
            ++it1;
        }
    }
    
    return collision;
}